import urllib2
from urllib import quote_plus
from simplejson import loads
from httplib import HTTPConnection
import urlparse

class connection:
    def __init__(self,url):
        self.baseurl=url
        self.sparql_prefix=""
        self.host=urlparse.urlparse(url).netloc
    
    def addnamespace(self,id,ns):
        self.sparql_prefix+='PREFIX %s:<%s>\n' % (id,ns) 
    
    def __getsparql__(self,method):
        req=urllib2.Request(self.baseurl+method,
                            headers={'Accept':'application/sparql-results+json'})
        data=urllib2.urlopen(req)
        data=data.read()
        try:
            result=loads(data)['results']['bindings']
            return result
        except:
            return [{'error':data}];
    
    def repositories(self):
        return self.__getsparql__('repositories')
        
    def use_repository(self,r):
        self.repository=r
    
    def query(self,q):
        q='repositories/'+self.repository+'?query='+quote_plus(self.sparql_prefix+q)
        return self.__getsparql__(q)
        
    def construct_query(self,q):
        q='repositories/'+self.repository+'?query='+quote_plus(self.sparql_prefix+q)
        data=urllib2.urlopen(urllib2.Request(self.baseurl+q,headers={'Accept':'application/sparql-results+json'})).read()
        return data

    def postdata(self,data,context=None):
        #host=self.baseurl+'/repositories/'+self.repository+'/statements?context=%3Chttp://semprog.com/pysesame%3E'
        host=self.baseurl+'/repositories/'+self.repository+'/statements'
        if context:
            host += '?context=' + quote_plus(context)
        res=urllib2.urlopen(urllib2.Request(host,data,{'Content-Type':'application/rdf+xml;charset=UTF-8'})).read()
        return res

    def __request__(self, method, path, data, headers):
        conn = HTTPConnection(self.host)
        conn.request(method, path, data, headers)
        response = conn.getresponse()
        if response.status != 200 and response.status != 204:
            raise Exception("Sessame connection error " +
                            str(response.status) + " " + response.reason)
        response = response.read()
        conn.close()
        return response

    def putdata(self,data,context=None):
        host=self.baseurl+'/repositories/'+self.repository+'/statements'
        if context:
            host += '?context=' + quote_plus(context)
        return self.__request__("PUT", host, data,
                                {'Content-Type':
                                 'application/rdf+xml;charset=UTF-8'})
        
if __name__=='__main__':

    c=connection('http://localhost:8080/openrdf-sesame/')
    c.use_repository('Movies')
    c.addnamespace('fb','http://rdf.freebase.com/ns/')
    c.addnamespace('dc','http://purl.org/dc/elements/1.1/')
    
    res=c.query("""SELECT ?costar ?fn WHERE {?film fb:film.film.performances ?p1 .
                   ?film dc:title ?fn .
                   ?p1 fb:film.performance.actor ?a1 . 
                   ?a1 dc:title "John Malkovich".
                   ?film fb:film.film.performances ?p2 .
                   ?p2 fb:film.performance.actor ?a2 . 
                   ?a2 dc:title ?costar .}""")

    for r in res:
        print r